package com.ly.mp.busicen.rule.instrumentation.plugin;

import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

import javax.annotation.PostConstruct;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import com.ly.mp.busicen.rule.flow.IDataVolume;
import com.ly.mp.busicen.rule.flow.IFlowContext;
import com.ly.mp.busicen.rule.flow.IFlowResult;
import com.ly.mp.busicen.rule.flow.IFlowResultCtn;
import com.ly.mp.busicen.rule.flow.IFlowVolume;
import com.ly.mp.busicen.rule.flow.action.IAction;
import com.ly.mp.busicen.rule.flow.action.IActionResult;
import com.ly.mp.busicen.rule.flow.filter.FlowFilter;
import com.ly.mp.busicen.rule.flow.filter.FlowInvocation;
import com.ly.mp.busicen.rule.flow.filter.FlowResult;
import com.ly.mp.busicen.rule.instrumentation.FlowInstrumentationException;
import com.ly.mp.busicen.rule.instrumentation.IFlowInstrumentation;

@Component
public class TriggerInstrumentation implements IFlowInstrumentation,ApplicationContextAware{
	
	@Autowired
	TriggerInstumentContainer triggerInstumentContainer;
	
	ApplicationContext applicationContext;
	
	ScheduledExecutorService executorService = Executors.newScheduledThreadPool(10);
	
	@PostConstruct
	void init() {
		Map<String, IXruleTriggerRegister> types = applicationContext.getBeansOfType(IXruleTriggerRegister.class);
		types.values().forEach(m->m.regist(triggerInstumentContainer));
	}
	

	@Override
	public void beginFlow(String flow, String brand, Map<String, Object> data, String rid) {		
		
	}

	@Override
	public void endBuildContext(IFlowContext context) {
		
	}

	@Override
	public void beginActionInvoke(IAction action, IFlowContext context, IFlowResultCtn result) {
		
	}

	@Override
	public void endActionInvoke(IAction action, IFlowContext context, IFlowResultCtn result, IFlowResult flowResult) {
		
	}

	@Override
	public void beginFilter(FlowFilter flowFilter, FlowInvocation invocation) {
		
	}
	
	@Override
	public void endFilter(FlowFilter flowFilter, FlowInvocation invocation, FlowResult filterResult) {
		
	}

	@Override
	public void beginActionExecute(IAction action, IDataVolume dataVolume, IFlowVolume flowVolume) {
		
	}

	@Override
	public void endActionExecute(IAction action, IDataVolume dataVolume, IFlowVolume flowVolume,
			IActionResult actionResult) {
		
	}

	@Override
	public void endFlow(IFlowResultCtn result) {
		triggerInstumentContainer.triggers(result.flowContext().flowVolume().flow()).forEach(m->{
			if (m.isSync()) {
				try {
					m.getTrigger().endFlow(result);
				} catch (Throwable e) {
					throw FlowInstrumentationException.create(e);
				}
			}else {
				executorService.execute(()->m.getTrigger().endFlow(result));
			}
			
		});
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext= applicationContext;		
	}


	@Override
	public String label() {
		return "trigger";
	}


	

}
